Tutorial 6: Manipulação de Dados com Tidyverse
Introdução.
Nas nossas duas primeiras semanas de aula, focamos em uma introdução básica ao R e a comunicar nossos resultados usando relatórios dinâmicos e de alta qualidade via RMarkdown.
Pelas próximas três semanas, focaremos em três habilidades centrais para nosso trabalha enquanto cientista social computacional: i) manipulação de banco de dados, b) visualização de dados, e c) programação funcional.
Para aprender estas três habilidades, faremos uso dos pacotes do tidyverse.
Tidyverse
O tidyverse é uma família de pacotes em R. Estes pacotes foram e são desenvolvidos de forma integrada, compartilhando uma mesma filosofia de design, gramática e estruturas de dados subjacentes. Portanto, se você aprender um, os outros pacotes ficarão mais fáceis.
O objetivo do tidyverse é prover um conjunto integrado de ferramentas para o uso do R como linguagem em Ciência de Dados. O que signifca que os pacotes do tidyverse cobrem temas como manipulação de dados, visualização, preparação, modelagem, limpeza, entre outros. Estes são os principais pacotes do tidyverse:
dplyr: para manipulação de dados.ggplot2: para visualização de dados.tidyr: para preparar seus dados para análise.purrr: para otimizar seu código e para programação funcional.readr: para abrir e organizar os dados.stringr: para manipulação de objetos de texto.forcats: para manipulação da classe fatores.
Porque devo usar o tidyverse ?
Você não deve usar o tidyverse. Porém, há diversas vantagens em usar os pacotes do tidyverse para sua dinâmica de trabalho em R. Algumas delas são:
O
tidyversefacilita substancialmente as tarefas de análise de dados quando comparado com códigos do R básico.Aumenta substancialmente quão legível seu código parece.
Manipulação, visualização e modelagem estão integradas no tidyverse.
É amplamente utilizado na comunidade de R. Portanto, provavelmente você precisa aprender para ler códigos no futuro.
No tutorial de hoje, faremos uma breve introdução ao tidyverse e em seguida focaremos no uso do do dplyr para manipulação de bancos de dados.
Entrando no Tidyverse
Instalação.
O primeiro passo é instalarmos o tidyverse. Com um comando, estamos instalando dezenas de pacotes em nosso R.
install.packages("tidyverse")library(tidyverse)Tibbles.
O objeto fundamental do tidyverse são bancos de dados. Sendo um pacote desenvolvido para ciência de dados, manipulação e visualização, todos os pacotes do tidyverse são desenvolvidos para funcionar com formatos básicos de banco de dados.
O tidyverse usa objetos chamados de “tibbles” para definir seus bancos de dados ao invés do tradicional data.frame que aprendemos semana passada. Tibbles são exatamente iguais a banco de dados em sua estrutura básica, no entanto, tibbles possuem alguns ajustes para facilitar sua aplicabilidade.
Criando Tibbles.
# Classe do Banco de Dados mtcars
class(mtcars)## [1] "data.frame"
# Converte para tibbles
mtcars_tib <- as_tibble(mtcars)
mtcars_tib## # A tibble: 32 x 11
## mpg cyl disp hp drat wt qsec vs am gear carb
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
## 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
## 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
## 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
## 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
## 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
## 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
## # … with 22 more rows
Pipe.
knitr::include_graphics("figs/pipe.jpg")O uso de pipes %>% é uma peça fundamental no funcionamento dos pacotes do tidyverse, em particular para processos de manipulação de bancos de dados.
O %>%permite a você concatenar, conectar em cadeias as funções do seu código. Esta conexão faz com que nossos códigos se tornem mais intuitivos e fáceis de serem lidos e interpretados.
Para entendermos a utilidade dos pipes, é bom perceber primeiro como o R conecta operações distintas.
O R funciona de dentro para fora:
# R
x <- c(1:10)
round(exp(sqrt(mean(x))), 1)## [1] 10.4
o %>% conecta estas operações em ordem lógica:
x %>%
mean() %>%
sqrt() %>%
exp() %>%
round(1) ## [1] 10.4
Notas importantes sobre os pipes.
1. Os pipes sempre devem ser usados para conectar funções e seus outputs.
# Não rode este código.
x %>%
funcao1(arg1=x) %>%
funcao2(arg=output_da_funcao1)Exemplo:
sample(1:1000, 500, replace=TRUE) %>%
density() %>% # funcao 1.
plot() # função 2. 2. O input sempre pode ser omitido, ou representados pelo atalho .
sample(1:1000, 500, replace=TRUE) %>%
density(.) %>% # funcao 1.
plot(.) # função 2. 3. Os resultados do pipe não são salvos imediatamente. Você precisa atribuir à um novo objeto.
grafico <- sample(1:1000, 500, replace=TRUE) %>%
density(.) %>% # funcao 1.
plot(.) # função 2. Desafio.
Reescreva o código abaixo utilizando o %>%.
library(tidyverse)
x <- "cpdoc"
x <- str_to_upper(x)
x <- str_c(x, "-FGV")
x <- str_to_title(x)
x## [1] "Cpdoc-Fgv"
Manipulação de dados com dplyr.
A partir deste ponto, focaremos no pacote dplyr para manipular e transformar banco de dados. Vamos utilizar dados eleitorais do Brasil, extraídos a partir do pacote cepespR, para tornar nosso aprendizado mais intuitivo
Dados Eleitorais: cepespR
if (!require("devtools")) install.packages("devtools")
devtools::install_github("Cepesp-Fgv/cepesp-r") library(cepespR)
library(tidyverse)
pres_rio <- get_votes(year = 2018,
position = "Presidente",
regional_aggregation = "Municipio",
state="RJ") %>%
as_tibble()Informações básicas
glimpse(pres_rio)## Rows: 1,374
## Columns: 19
## $ ANO_ELEICAO <int> 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 201…
## $ SIGLA_UE <chr> "BR", "BR", "BR", "BR", "BR", "BR", "BR", "BR", "BR…
## $ NUM_TURNO <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ DESCRICAO_ELEICAO <chr> "ELEIÇÃO GERAL FEDERAL 2018", "ELEIÇÃO GERAL FEDERA…
## $ CODIGO_CARGO <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ DESCRICAO_CARGO <chr> "PRESIDENTE", "PRESIDENTE", "PRESIDENTE", "PRESIDEN…
## $ NUMERO_CANDIDATO <int> 12, 13, 15, 16, 17, 18, 19, 27, 30, 45, 50, 51, 54,…
## $ CODIGO_MACRO <int> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, …
## $ NOME_MACRO <chr> "Sudeste", "Sudeste", "Sudeste", "Sudeste", "Sudest…
## $ UF <chr> "RJ", "RJ", "RJ", "RJ", "RJ", "RJ", "RJ", "RJ", "RJ…
## $ NOME_UF <chr> "Rio de Janeiro", "Rio de Janeiro", "Rio de Janeiro…
## $ CODIGO_MESO <int> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, …
## $ NOME_MESO <chr> "Sul Fluminense", "Sul Fluminense", "Sul Fluminense…
## $ CODIGO_MICRO <int> 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,…
## $ NOME_MICRO <chr> "Baía da Ilha Grande", "Baía da Ilha Grande", "Baía…
## $ COD_MUN_TSE <int> 58017, 58017, 58017, 58017, 58017, 58017, 58017, 58…
## $ COD_MUN_IBGE <int> 3300100, 3300100, 3300100, 3300100, 3300100, 330010…
## $ NOME_MUNICIPIO <chr> "Angra dos Reis", "Angra dos Reis", "Angra dos Reis…
## $ QTDE_VOTOS <int> 8696, 13204, 565, 34, 59499, 662, 349, 32, 998, 190…
Introdução ao Dplyr.
O dplyr é um dos pacotes mais populares em R. Sua lógica é simples: suas funções fazem exatamente o que seus nomes descrevem (verb based language). Seu uso torna nosso código mais intuitivo de seguir, entender e ler. Veja alguns exemplos.
Estas são as funções mais úteis do dplyr:
select(): selecionar colunas.filter(): filtrar o banco de dados por linhas.mutate(): criar novas variáveis e alterar existentes.arrange(): ordenar o banco de dados.group_by(): agrupar e fazer análiser nos subgrupos.summarize(): sumariza os dados por subgroups.
Algumas outras funções menos utilizadas:
count(): contar número de observações por subgrupos.distinct(): eliminar repetições.n():conta quantas observações há em dados agrupados.sample_n():Selecion n amostras do seu banco de dadoslglimpse():Fornece um sumário dos seus dados.top_n():Seleciona por linhas de acordo com o rank das variáveis.slice(): filtra seu banco de dados por posições.
Todas essas funções seguem as mesmas características:
O input é sempre um banco de dados.
O banco de dados é sempre o primeiro argumento.
Os argumentos seguintes acessão colunas dos bancos de dados diretamente, sem aspas.
O output é sempre um novo banco de dados.
Select: Seleciona Colunas.
Uso Básico.
pres_rio %>% # Dados
select(ANO_ELEICAO, SIGLA_UE, NOME_MUNICIPIO, COD_MUN_IBGE) # colunas## # A tibble: 1,374 x 4
## ANO_ELEICAO SIGLA_UE NOME_MUNICIPIO COD_MUN_IBGE
## <int> <chr> <chr> <int>
## 1 2018 BR Angra dos Reis 3300100
## 2 2018 BR Angra dos Reis 3300100
## 3 2018 BR Angra dos Reis 3300100
## 4 2018 BR Angra dos Reis 3300100
## 5 2018 BR Angra dos Reis 3300100
## 6 2018 BR Angra dos Reis 3300100
## 7 2018 BR Angra dos Reis 3300100
## 8 2018 BR Angra dos Reis 3300100
## 9 2018 BR Angra dos Reis 3300100
## 10 2018 BR Angra dos Reis 3300100
## # … with 1,364 more rows
Reordenando Colunas
pres_rio %>% # Dados
# seleciona colunas
select(QTDE_VOTOS, ANO_ELEICAO, SIGLA_UE,
NOME_MUNICIPIO, COD_MUN_IBGE) # colunas## # A tibble: 1,374 x 5
## QTDE_VOTOS ANO_ELEICAO SIGLA_UE NOME_MUNICIPIO COD_MUN_IBGE
## <int> <int> <chr> <chr> <int>
## 1 8696 2018 BR Angra dos Reis 3300100
## 2 13204 2018 BR Angra dos Reis 3300100
## 3 565 2018 BR Angra dos Reis 3300100
## 4 34 2018 BR Angra dos Reis 3300100
## 5 59499 2018 BR Angra dos Reis 3300100
## 6 662 2018 BR Angra dos Reis 3300100
## 7 349 2018 BR Angra dos Reis 3300100
## 8 32 2018 BR Angra dos Reis 3300100
## 9 998 2018 BR Angra dos Reis 3300100
## 10 1909 2018 BR Angra dos Reis 3300100
## # … with 1,364 more rows
Renomeando Colunas
pres_rio %>%
# seleciona colunas com novos nomes.
select(votos=QTDE_VOTOS,
ano=ANO_ELEICAO,
pais=SIGLA_UE,
mun=NOME_MUNICIPIO,
cod=COD_MUN_IBGE) # colunas## # A tibble: 1,374 x 5
## votos ano pais mun cod
## <int> <int> <chr> <chr> <int>
## 1 8696 2018 BR Angra dos Reis 3300100
## 2 13204 2018 BR Angra dos Reis 3300100
## 3 565 2018 BR Angra dos Reis 3300100
## 4 34 2018 BR Angra dos Reis 3300100
## 5 59499 2018 BR Angra dos Reis 3300100
## 6 662 2018 BR Angra dos Reis 3300100
## 7 349 2018 BR Angra dos Reis 3300100
## 8 32 2018 BR Angra dos Reis 3300100
## 9 998 2018 BR Angra dos Reis 3300100
## 10 1909 2018 BR Angra dos Reis 3300100
## # … with 1,364 more rows
Salvando Novo Banco.
rio_reduzido <- pres_rio %>% # Dados
# seleciona colunas com novos nomes.
select(votos=QTDE_VOTOS,
ano=ANO_ELEICAO,
pais=SIGLA_UE,
mun=NOME_MUNICIPIO,
cod=COD_MUN_IBGE) # colunasOutros Atalhos para Uso do Select.
contains()- Extrai colunas que contêm determinado texto.starts_with()- Extrai colunas que inicia com determinado texto.ends_with()- Extrai colunas que termina com determinado texto.everything()- Extrai todas as colunas restantes.
Exemplos
pres_rio %>%
# seleciona colunas onde NOME aparece
select(contains("NOME"))## # A tibble: 1,374 x 5
## NOME_MACRO NOME_UF NOME_MESO NOME_MICRO NOME_MUNICIPIO
## <chr> <chr> <chr> <chr> <chr>
## 1 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 2 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 3 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 4 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 5 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 6 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 7 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 8 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 9 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## 10 Sudeste Rio de Janeiro Sul Fluminense Baía da Ilha Grande Angra dos Reis
## # … with 1,364 more rows
pres_rio %>%
# seleciona colunas que terminam com UF e
# todas as outras colunas restantes
select(ends_with("UF"), everything())## # A tibble: 1,374 x 19
## UF NOME_UF ANO_ELEICAO SIGLA_UE NUM_TURNO DESCRICAO_ELEIC… CODIGO_CARGO
## <chr> <chr> <int> <chr> <int> <chr> <int>
## 1 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## 2 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## 3 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## 4 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## 5 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## 6 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## 7 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## 8 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## 9 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## 10 RJ Rio de… 2018 BR 1 ELEIÇÃO GERAL F… 1
## # … with 1,364 more rows, and 12 more variables: DESCRICAO_CARGO <chr>,
## # NUMERO_CANDIDATO <int>, CODIGO_MACRO <int>, NOME_MACRO <chr>,
## # CODIGO_MESO <int>, NOME_MESO <chr>, CODIGO_MICRO <int>, NOME_MICRO <chr>,
## # COD_MUN_TSE <int>, COD_MUN_IBGE <int>, NOME_MUNICIPIO <chr>,
## # QTDE_VOTOS <int>
Filter: Filtra Linhas por Condições Lógicas.
Uso Básico.
filter(data, coluna=="a")
pres_rio %>%
# filtra casos ondem partido igual a 17.
filter(NUMERO_CANDIDATO==17) %>%
# seleciona
select(DESCRICAO_CARGO, NUMERO_CANDIDATO, QTDE_VOTOS, NOME_MUNICIPIO)## # A tibble: 184 x 4
## DESCRICAO_CARGO NUMERO_CANDIDATO QTDE_VOTOS NOME_MUNICIPIO
## <chr> <int> <int> <chr>
## 1 PRESIDENTE 17 59499 Angra dos Reis
## 2 PRESIDENTE 17 4366 Aperibé
## 3 PRESIDENTE 17 44108 Araruama
## 4 PRESIDENTE 17 3816 Areal
## 5 PRESIDENTE 17 13028 Armação dos Búzios
## 6 PRESIDENTE 17 13342 Arraial do Cabo
## 7 PRESIDENTE 17 27178 Barra do Piraí
## 8 PRESIDENTE 17 55972 Barra Mansa
## 9 PRESIDENTE 17 138676 Belford Roxo
## 10 PRESIDENTE 17 8077 Bom Jardim
## # … with 174 more rows
Multiplas Condições
pres_rio %>%
# filtra usando or
filter(NUMERO_CANDIDATO==17 | NUMERO_CANDIDATO==13, # or
#filtra usando and
NOME_MUNICIPIO=="Rio de Janeiro") %>% # and
#selecion
select(DESCRICAO_CARGO, NUMERO_CANDIDATO, QTDE_VOTOS, NOME_MUNICIPIO)## # A tibble: 4 x 4
## DESCRICAO_CARGO NUMERO_CANDIDATO QTDE_VOTOS NOME_MUNICIPIO
## <chr> <int> <int> <chr>
## 1 PRESIDENTE 13 398033 Rio de Janeiro
## 2 PRESIDENTE 17 1930657 Rio de Janeiro
## 3 PRESIDENTE 13 1105393 Rio de Janeiro
## 4 PRESIDENTE 17 2179896 Rio de Janeiro
Arrange: Ordena Linhas por Colunas.
Uso Básico:
arrange(data, coluna)
pres_rio %>%
# filtra pelas linhas
filter(NUMERO_CANDIDATO==13) %>%
# seleciona
select(DESCRICAO_CARGO, NUMERO_CANDIDATO,
QTDE_VOTOS, NOME_MUNICIPIO) %>%
# ordena de forma crescente
arrange(QTDE_VOTOS)## # A tibble: 184 x 4
## DESCRICAO_CARGO NUMERO_CANDIDATO QTDE_VOTOS NOME_MUNICIPIO
## <chr> <int> <int> <chr>
## 1 PRESIDENTE 13 830 São José do Vale do Rio Preto
## 2 PRESIDENTE 13 1111 Areal
## 3 PRESIDENTE 13 1115 Santa Maria Madalena
## 4 PRESIDENTE 13 1129 Aperibé
## 5 PRESIDENTE 13 1152 São José de Ubá
## 6 PRESIDENTE 13 1224 Macuco
## 7 PRESIDENTE 13 1241 Varre-Sai
## 8 PRESIDENTE 13 1342 Italva
## 9 PRESIDENTE 13 1448 São Sebastião do Alto
## 10 PRESIDENTE 13 1455 Duas Barras
## # … with 174 more rows
Decrescente
pres_rio %>%
# filtra pelas linhas
filter(NUMERO_CANDIDATO==13) %>%
# seleciona variáveis
select(DESCRICAO_CARGO, NUMERO_CANDIDATO,
QTDE_VOTOS, NOME_MUNICIPIO) %>%
# ordena em valores descrecentes
arrange(desc(QTDE_VOTOS))## # A tibble: 184 x 4
## DESCRICAO_CARGO NUMERO_CANDIDATO QTDE_VOTOS NOME_MUNICIPIO
## <chr> <int> <int> <chr>
## 1 PRESIDENTE 13 1105393 Rio de Janeiro
## 2 PRESIDENTE 13 398033 Rio de Janeiro
## 3 PRESIDENTE 13 149075 São Gonçalo
## 4 PRESIDENTE 13 136240 Duque de Caxias
## 5 PRESIDENTE 13 110820 Nova Iguaçu
## 6 PRESIDENTE 13 105606 Niterói
## 7 PRESIDENTE 13 80858 São Gonçalo
## 8 PRESIDENTE 13 79838 Campos dos Goytacazes
## 9 PRESIDENTE 13 77504 Duque de Caxias
## 10 PRESIDENTE 13 70499 São João de Meriti
## # … with 174 more rows
Mutate: Adiciona uma nova coluna.
Uso Básico:
mutate(data, nome_nova_coluna=valores_nova_coluna)
pres_rio %>%
# cria variável com estado e cidade
mutate(estado_cidade=paste(NOME_MUNICIPIO, "-", NOME_UF)) %>%
#seleciona para visualizar
select(NOME_MUNICIPIO, NOME_UF, estado_cidade)## # A tibble: 1,374 x 3
## NOME_MUNICIPIO NOME_UF estado_cidade
## <chr> <chr> <chr>
## 1 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 2 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 3 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 4 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 5 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 6 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 7 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 8 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 9 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## 10 Angra dos Reis Rio de Janeiro Angra dos Reis - Rio de Janeiro
## # … with 1,364 more rows
Condicionais
pres_rio %>%
# cria variável usando condicionais
mutate(estado_sigla=ifelse(NOME_UF=="Rio de Janeiro", "RJ", NA),
# concatena nova variável com cidade
estado_cidade=paste(estado_sigla, "-", NOME_MUNICIPIO)) %>%
#selectiona
select(NOME_UF, NOME_MUNICIPIO, estado_sigla, everything())## # A tibble: 1,374 x 21
## NOME_UF NOME_MUNICIPIO estado_sigla ANO_ELEICAO SIGLA_UE NUM_TURNO
## <chr> <chr> <chr> <int> <chr> <int>
## 1 Rio de… Angra dos Reis RJ 2018 BR 1
## 2 Rio de… Angra dos Reis RJ 2018 BR 1
## 3 Rio de… Angra dos Reis RJ 2018 BR 1
## 4 Rio de… Angra dos Reis RJ 2018 BR 1
## 5 Rio de… Angra dos Reis RJ 2018 BR 1
## 6 Rio de… Angra dos Reis RJ 2018 BR 1
## 7 Rio de… Angra dos Reis RJ 2018 BR 1
## 8 Rio de… Angra dos Reis RJ 2018 BR 1
## 9 Rio de… Angra dos Reis RJ 2018 BR 1
## 10 Rio de… Angra dos Reis RJ 2018 BR 1
## # … with 1,364 more rows, and 15 more variables: DESCRICAO_ELEICAO <chr>,
## # CODIGO_CARGO <int>, DESCRICAO_CARGO <chr>, NUMERO_CANDIDATO <int>,
## # CODIGO_MACRO <int>, NOME_MACRO <chr>, UF <chr>, CODIGO_MESO <int>,
## # NOME_MESO <chr>, CODIGO_MICRO <int>, NOME_MICRO <chr>, COD_MUN_TSE <int>,
## # COD_MUN_IBGE <int>, QTDE_VOTOS <int>, estado_cidade <chr>
Operações Matemáticas.
pres_rio %>%
# log dos votos
mutate(log_votos=log(QTDE_VOTOS)) %>%
# seleciona
select(QTDE_VOTOS, log_votos)## # A tibble: 1,374 x 2
## QTDE_VOTOS log_votos
## <int> <dbl>
## 1 8696 9.07
## 2 13204 9.49
## 3 565 6.34
## 4 34 3.53
## 5 59499 11.0
## 6 662 6.50
## 7 349 5.86
## 8 32 3.47
## 9 998 6.91
## 10 1909 7.55
## # … with 1,364 more rows
Group_by + Summarize.
Uma tarefa muito comum quando manipulamos bancos de dados é calcular valores para determinados subgroups. Por exemplo:
Qual a votação total dos candidatos a presidencia no Estado do Rio de Janeiro ?
Qual o total de votos por município?
Em qual micro-região Jair Bolsonaro saiu com maior vantagem?
Para responder esta perguntas, faremos uso da função group_by + summarize.
Group_by
O primeiro passo é agrupar de acordo com a variável de nosso interesse.
pres_rio %>%
# agrupando por candidato presidencial
group_by(NUMERO_CANDIDATO) ## # A tibble: 1,374 x 19
## # Groups: NUMERO_CANDIDATO [13]
## ANO_ELEICAO SIGLA_UE NUM_TURNO DESCRICAO_ELEIC… CODIGO_CARGO DESCRICAO_CARGO
## <int> <chr> <int> <chr> <int> <chr>
## 1 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 2 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 3 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 4 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 5 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 6 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 7 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 8 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 9 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 10 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## # … with 1,364 more rows, and 13 more variables: NUMERO_CANDIDATO <int>,
## # CODIGO_MACRO <int>, NOME_MACRO <chr>, UF <chr>, NOME_UF <chr>,
## # CODIGO_MESO <int>, NOME_MESO <chr>, CODIGO_MICRO <int>, NOME_MICRO <chr>,
## # COD_MUN_TSE <int>, COD_MUN_IBGE <int>, NOME_MUNICIPIO <chr>,
## # QTDE_VOTOS <int>
group_by somente agrupa seu banco. É como se criassêmos diversos mini-bancos de dados no background do R. A partir disso, podemos usar summarize para calcular valores de nosso interesse neste subgrupos.
Summarize.
Uso básico:
summarize(dados_agrupados, nome_nova_variavel=valores_calculados)
pres_rio %>%
# Somente primeiro turno
filter(NUM_TURNO==1) %>%
# agrupando por candidato presidencial
group_by(NUMERO_CANDIDATO) %>%
# Somando os votos em todo o estado.
summarise(voto_estado=sum(QTDE_VOTOS)) %>%
# Ordena
arrange(desc(voto_estado))## # A tibble: 13 x 2
## NUMERO_CANDIDATO voto_estado
## <int> <int>
## 1 17 5107735
## 2 12 1300292
## 3 13 1255425
## 4 51 211444
## 5 45 208325
## 6 30 139208
## 7 18 130794
## 8 15 77333
## 9 50 57846
## 10 19 41544
## 11 16 6005
## 12 27 4636
## 13 54 2806
Perceba: o summarize transforma múltiplas linhas em uma para cada subgrupo
Mais Exemplos
Quem ganhou no Rio de Janeiro no Segundo Turno?
pres_rio %>%
# Somente primeiro turno
filter(NUM_TURNO==2) %>%
# agrupando por candidato presidencial
group_by(NUMERO_CANDIDATO) %>%
# Somando os votos em todo o estado.
summarise(voto_estado=sum(QTDE_VOTOS)) %>%
# Ordena
arrange(desc(voto_estado))## # A tibble: 2 x 2
## NUMERO_CANDIDATO voto_estado
## <int> <int>
## 1 17 5669059
## 2 13 2673386
Total de Votos por Município
pres_rio %>%
# Somente primeiro turno
filter(NUM_TURNO==1) %>%
# agrupando por candidato presidencial
group_by(NOME_MUNICIPIO) %>%
# Somando os votos em todo o estado.
summarise(voto_mun=sum(QTDE_VOTOS)) ## # A tibble: 92 x 2
## NOME_MUNICIPIO voto_mun
## * <chr> <int>
## 1 Angra dos Reis 88316
## 2 Aperibé 6680
## 3 Araruama 64481
## 4 Areal 6921
## 5 Armação dos Búzios 19979
## 6 Arraial do Cabo 20133
## 7 Barra do Piraí 48942
## 8 Barra Mansa 96980
## 9 Belford Roxo 226785
## 10 Bom Jardim 14090
## # … with 82 more rows
Votos por Meso-Região
pres_rio %>%
# Somente primeiro turno
filter(NUM_TURNO==1) %>%
# agrupando por candidato presidencial
group_by(NUMERO_CANDIDATO, NOME_MESO) %>%
# soma de votos por município
summarise(voto_media=mean(QTDE_VOTOS),
voto_min=min(QTDE_VOTOS),
voto_max=max(QTDE_VOTOS))## # A tibble: 78 x 5
## # Groups: NUMERO_CANDIDATO [13]
## NUMERO_CANDIDATO NOME_MESO voto_media voto_min voto_max
## <int> <chr> <dbl> <int> <int>
## 1 12 Baixadas 4769. 1157 13478
## 2 12 Centro Fluminense 2558 403 16254
## 3 12 Metropolitana do Rio de Janeiro 35187. 702 645674
## 4 12 Noroeste Fluminense 1393. 296 4684
## 5 12 Norte Fluminense 6909. 798 33042
## 6 12 Sul Fluminense 5412. 812 23860
## 7 13 Baixadas 4409. 1574 10310
## 8 13 Centro Fluminense 2954. 1111 10664
## 9 13 Metropolitana do Rio de Janeiro 31261. 830 398033
## 10 13 Noroeste Fluminense 2789. 1129 8209
## # … with 68 more rows
Outras funções úteis.
Count: Contar por grupos.
pres_rio %>%
# Quantas entradas para cada número candidato?
count(NUMERO_CANDIDATO)## # A tibble: 13 x 2
## NUMERO_CANDIDATO n
## * <int> <int>
## 1 12 92
## 2 13 184
## 3 15 92
## 4 16 91
## 5 17 184
## 6 18 92
## 7 19 92
## 8 27 92
## 9 30 92
## 10 45 92
## 11 50 92
## 12 51 92
## 13 54 87
Slice: Selecionar por posição das linhas.
pres_rio %>%
slice(1:10)## # A tibble: 10 x 19
## ANO_ELEICAO SIGLA_UE NUM_TURNO DESCRICAO_ELEIC… CODIGO_CARGO DESCRICAO_CARGO
## <int> <chr> <int> <chr> <int> <chr>
## 1 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 2 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 3 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 4 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 5 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 6 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 7 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 8 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 9 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## 10 2018 BR 1 ELEIÇÃO GERAL F… 1 PRESIDENTE
## # … with 13 more variables: NUMERO_CANDIDATO <int>, CODIGO_MACRO <int>,
## # NOME_MACRO <chr>, UF <chr>, NOME_UF <chr>, CODIGO_MESO <int>,
## # NOME_MESO <chr>, CODIGO_MICRO <int>, NOME_MICRO <chr>, COD_MUN_TSE <int>,
## # COD_MUN_IBGE <int>, NOME_MUNICIPIO <chr>, QTDE_VOTOS <int>
rowid_to_column() : criar id para linhas
pres_rio %>%
rowid_to_column() %>%
select(1:5)## # A tibble: 1,374 x 5
## rowid ANO_ELEICAO SIGLA_UE NUM_TURNO DESCRICAO_ELEICAO
## <int> <int> <chr> <int> <chr>
## 1 1 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## 2 2 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## 3 3 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## 4 4 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## 5 5 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## 6 6 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## 7 7 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## 8 8 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## 9 9 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## 10 10 2018 BR 1 ELEIÇÃO GERAL FEDERAL 2018
## # … with 1,364 more rows
Desafio
Mutate x Summarize.
Qual a diferença entre as funções mutate and summarize ? Porque os dois exemplos abaixo geram resultados distintos?
# Exemplo: Mutate
pres_rio %>%
# Somente primeiro turno
filter(NUM_TURNO==1) %>%
# group## Error: <text>:7:0: unexpected end of input
## 5: # group
## 6:
## ^
Praticando:
Abre o banco de dados de candidatos a deputado federal no Rio de Janeiro.
dep_rio <- get_candidates(year=2018,
position="Federal Deputy") %>%
as_tibble()Responda:
- Qual partido elegeu mais deputados? (3 linhas)
Dica: data %>% filter(COD_SIT_TOT_TURNO==2 | COD_SIT_TOT_TURNO==3) filtra somente os eleitos.
Qual candidato gastou mais recursos ? (2-3 linhas)
Qual valor médio declarado de gastos de campanha de acordo com o gênero dos candidatos? (3 linhas)
Conectando Bancos de Dados com Dplyr.
Raramente, você encontrará um banco de dados onde todas as informações da sua pesquisa estão contidas e prontas para serem analisadas.
Na maioria dos casos, e por boas razões, bancos de dados possuem informações distintas, e os pesquisadores precisamos conectá-los com vistas a construir o material necessário para suas análises.
Este tipo de dados conectados a partir de várias tabelas são chamados de dados relacionais. dados eleitorais no Brasil providos pelo TSE vem em pedaços distintos de informação, que podem a depender dos objetivos de sua análise ser conectados. De forma mais concreta, estes são alguns exemplos de bancos disponíveis no TSE
Candidatos: arrecadação, nome, profissão, etc.
Votação: dados de votação por município, zonal, seção eleitoral.
Eleitorado: perfil dos eleitores registrados no nível da zona eleitoral.
Chaves (keys)
Ainda nos casos dos bancos de dados do TSE, por exemplo, usando o número do candidato e a unidade eleitoral é possível conectar os bancos de candidatos e votação, ou usando o número da zona eleitoral por município, conectar votação e eleitorado.
Estas variáveis capazes de conectar bancos de dados são chamadas chaves. Estas chaves são:
Completas. Nunca tenha missing values nas suas chaves.
Únicas: cada observação deve possuir uma chave distinta. Evite sempre duplicações.
Joins
Inspirado na linguaguem SQL, o dplyr possui um conjunto de funções com foco em conectar bancos de dados distintos.
Vamos criar dois bancos bem simples para entendermos como estes joins funcionam.
data1 <- tibble(nome=c("A", "B", "C"),
value=c(10, 20, 30))
data2 <- tibble(nome=c("A", "D", "C"),
value2=c(10, 50, 30))left_join()
left_join(data1, data2)## # A tibble: 3 x 3
## nome value value2
## <chr> <dbl> <dbl>
## 1 A 10 10
## 2 B 20 NA
## 3 C 30 30
inner_join()
inner_join(data1, data2)## # A tibble: 2 x 3
## nome value value2
## <chr> <dbl> <dbl>
## 1 A 10 10
## 2 C 30 30
full_join()
full_join(data1, data2)## # A tibble: 4 x 3
## nome value value2
## <chr> <dbl> <dbl>
## 1 A 10 10
## 2 B 20 NA
## 3 C 30 30
## 4 D NA 50
Chaves Distintas?
Em inúmeros casos, os bancos que precisamos conectar terá nomes diferentes. Este problema é fácil de resolver. É preciso adicionar o argumento dos nomes, e ajudar as funções joins a fazerem seu serviço.
data3 <- data2 %>%
# alterando o nome
select(chave=nome, everything())
# Join
left_join(data1, data3,
by=c("nome"="chave")) # adicione argumento by.## # A tibble: 3 x 3
## nome value value2
## <chr> <dbl> <dbl>
## 1 A 10 10
## 2 B 20 NA
## 3 C 30 30
Desafio
Abre os bancos de dados de candidatos e votos do TSE. Faça um join entre eles, e salve o banco de dados.
Quantas linhas este novo banco de dados possuí?
Explique o número de linhas.
# Banco Candidatos
candidatos <- get_candidates(year=2018, position="President") %>%
as_tibble()
# Banco Votos
votos <- get_votes(year = 2018, position="President", state="RJ") %>%
as_tibble()
# Join? Concatenando Bancos de Dados
Além de juntar bancos de dados usando chaves, podemos concatecar bancos verticalmente (pelas linhas) ou horizontalmente (pelas colunas).
bind_rows: por linhas
bind_rows(data1, data2)## # A tibble: 6 x 3
## nome value value2
## <chr> <dbl> <dbl>
## 1 A 10 NA
## 2 B 20 NA
## 3 C 30 NA
## 4 A NA 10
## 5 D NA 50
## 6 C NA 30
Note: ao conectar por linha, as colunas precisam ter os mesmos nomes. Caso não, você adicionará uma nova variável ao resultado final.
bind_cols: por colunas
bind_cols(data1, data2)## # A tibble: 3 x 4
## nome...1 value nome...3 value2
## <chr> <dbl> <chr> <dbl>
## 1 A 10 A 10
## 2 B 20 D 50
## 3 C 30 C 30
Note: ao conectar por coluna, as linhas precisam ter tamanho igual.